/**
* 通过crypto-js实现 加解密工具
* AES、DES、HASH(MD5、SHA256)、base64
* @author: taiping
*/
import CryptoJS from 'crypto-js'
export interface CryptoType {
  enAes: any;
  deAes: any;
  md5: any;
  sha256: any;
  base64: any;
  sign: any;
}

export default class Crypto implements CryptoType{
  private key = 'wit20dk9-n46K09r';
  private iv = this.getHetKey();
  private getHetKey() {
    return CryptoJS.enc.Utf8.parse(this.key);
  }
  /**
   * Aes 加密
   * @param data 加密的数据
   * KEY: 需要前后端保持一致
   * mode: ECB  需要前后端保持一致
   * pad: Pkcs7 前端 Pkcs7 对应 后端 Pkcs5
   */
  enAes = (data: string) => {
    const src = CryptoJS.enc.Utf8.parse(data);
    const enAes = CryptoJS.AES.encrypt(src, this.key, {
      iv: this.iv,
      mode: CryptoJS.mode.CBC,
      padding: CryptoJS.pad.Pkcs7,
    })
    return enAes.ciphertext.toString().toUpperCase();
  }

  /**
   * Aes 解密
   * @param data 需要解密的数据
   */
  deAes = (data: string) => {
    const enCryptoHexStr = CryptoJS.enc.Hex.parse(data);
    const src = CryptoJS.enc.Base64.stringify(enCryptoHexStr);
    const deCrypto = CryptoJS.AES.decrypt(src, this.key, {
      iv: this.iv,
      mode: CryptoJS.mode.ECB,
      padding: CryptoJS.pad.Pkcs7,
    })
    const deCryptoStr = deCrypto.toString(CryptoJS.enc.Utf8);
    return deCryptoStr.toString();
  }
  /**
   * md5加密
   * @param data
   */
  md5 = (data: any) => {
    return CryptoJS.MD5(data).toString();
  }
  /**
   * SHA256
   * @param data
   */
  sha256 = (data: any) => {
    return CryptoJS.SHA256(data).toString();
  }
  /**
   * BASE64
   */
  base64 = {
    en: (data) => CryptoJS.enc.Base64.stringify(CryptoJS.enc.Utf8.parse(data)),
    de: (data) => CryptoJS.enc.Base64.parse(data).toString(CryptoJS.enc.Utf8),
  }
  /**
   * 签名
   * @param token 身份令牌
   * @param timestamp 签名时间戳
   * @param data 签名数据
   */
  sign = (token, timestamp, data) => {
    // 签名格式： timestamp + token + data(字典升序)
    let ret = []
    for (let it in data) {
      let val = data[it]
      if (typeof val === 'object' &&
          (!(val instanceof Array) || (val.length > 0 && (typeof val[0] === 'object')))) {
        val = JSON.stringify(val)
      }
      ret.push(it + val)
    }
    // 字典升序
    ret.sort()
    let signSrc = timestamp + token + ret.join('')
    return this.md5(signSrc)
  }
}
